-- card: 16339 from stack: in.3 -- bmap block id: 16385 -- flags: 4000 -- background id: 7836 -- name: MenuHandler ----- HyperTalk script ----- on openCard global checked put false into checked pass openCard end openCard on closecard RemoveMenu set the name of btn 1 to "Install Menu" end closecard on InstallMenu global ExampleMenu put "(Disabled,Check,Test/A" into ExampleMenu MenuHandler "Add","Example",ExampleMenu MenuHandler "Disable","Go","Back" answer "Disabled HyperCard's 'go Back' menu item." end InstallMenu on RemoveMenu MenuHandler "Delete",Example MenuHandler "Enable","Go","Back" end RemoveMenu on domenu anItem global ExampleMenu, Disabled --anItem is the name of the menu item choosen -- HelpMenu is a list of items in my own help menu -- Disabled is the list of items that I have disabled if Disabled contains anItem then answer "HyperCard menu item "&anItem&" is disabled" with "OK" exit domenu else if ExampleMenu contains anItem then DoExample anItem -- see which item it is and do something else -- is an enable HyperCard item pass domenu -- pass it on down the line exit domenu end if end domenu on DoExample anItem global checked if anItem is "Check" then if checked is not true then MenuHandler "Mark","Example","Check",check put true into checked else MenuHandler "Mark","Example","Check",none put false into checked end if else if anItem is "Test" then answer "You have chosen the Test menu item." end if end DoExample -- part 3 (button) -- low flags: 00 -- high flags: A003 -- rect: left=76 top=298 right=320 bottom=176 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Install Menu ----- HyperTalk script ----- on mouseUp global ExampleMenu if the short name of me is "Install Menu" then InstallMenu -- see card script set the name of me to "Remove Menu" else RemoveMenu -- see card script set the name of me to "Install Menu" end if end mouseUp -- part 5 (field) -- low flags: 01 -- high flags: 2007 -- rect: left=18 top=32 right=288 bottom=480 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: Documentation -- part 6 (button) -- low flags: 00 -- high flags: A003 -- rect: left=284 top=298 right=320 bottom=453 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Show C Source: part 1 ----- HyperTalk script ----- on mouseUp if the short name of me is "Show C Source: part 1" then set the visible of card field "source1" to true set the visible of card field "source2" to false set the name of me to "Show C Source: part 2" else if the short name of me is "Show C Source: part 2" then set the visible of card field "source2" to true set the visible of card field "source1" to false set the name of me to "Hide C Source" else set the visible of card field "source2" to false set the visible of card field "source1" to false set the name of me to "Show C Source: part 1" end if end mouseUp -- part 7 (field) -- low flags: 81 -- high flags: 0007 -- rect: left=18 top=31 right=289 bottom=492 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: source1 -- part 8 (field) -- low flags: 81 -- high flags: 0007 -- rect: left=18 top=31 right=289 bottom=492 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: source2 -- part contents for card part 5 ----- text ----- MenuHandler version 1.2d10 Roger Brown version 1.2d7 note: interface to "show" command has changed. See below. MenuHandler is an XCMD that gives you the ability to add and manipulate your own menus in a HyperCard stack. You can add and delete whole menus and items from menus. You can set and unset check marks. You can change the names of HyperCard's menus and items in them, but this is not advised because HyperCard handles its own menus in a special way. You can, however, hide HyperCard's menus or disable items in them using some features of this XCMD. To use this XCMD you will have to install your own DoMenu handler and maintain some special globals. These are explained below. Note: This version does not support hierarchical menus. Warning: Does not work with menu patches for large Radius screens. INVOKING MENUHANDLER HyperCard Syntax is: MenuHandler opcode,title,other things according to opcode it returns: error messages where the opcodes are: Add - adds a new menu parameters are title,item string,before title is the menu title items is string containing the menu items and their states in the normal Mac ToolBox format except for commas instead of semi-colons to make hypertalk level processing easier before is a string that names a menu to insert this one before (if empty, this menu goes at the end of the menu bar) Delete - deletes a menu and its handle parameter is title Hide - hides a menu but remembers it for later restoration parameter is title Show - restores a hidden menu parameter is title,beforeMenu (used to be afterMenu) where after menu can be specified or the default is after all menus (used to be its original position, but it never worked) Insert - inserts a menu item parameters are menu title, item name with format specifications, after item (number or name) Remove - removes a menu item parameters are menu title, item name or number Enable - enables a menu item parameters are menu title, item name or number A number of 0 enables the whole menu Disable - disables a menu item parameters are menu title, item name or number A number of 0 disables the whole menu Mark - checks an item parameters are menu title, item name or number and mark: none,command,check,diamond, or apple To compile: create a project with this and MacTraps. Build as code resource type XCMD named MenuHandler. EXAMPLE ex. MenuHandler "Add","Help","Introduction,(----,Glossary" SPECIAL GLOBALS A HyperCard global is maintained for every menu added through MenuHandler. The global has the same name as the menu. The menu items in a menu are found in a HyperCard item list contained in a global whose name is the name of the menu concatenated with the word "Menu" . This makes it easy to test if a doMenu call is for an added menu. ex. global HelpMenu = "Introduction,Getting Started,Glossary" An extra global is maintained that includes a list of all items that are currently disabled. These can be in new menus or in HyperCard's menus. This list is needed because some HyperCard menu actions can still proceed even when their menu items appear to be disabled. DOMENU HANDLER To use MenuHandler, you need to have your own DoMenu handler to see if the menu action is one of your own. If it isn't then you pass it on to HyperCard. Another reason to have your own DoMenu handler is to catch HyperCard menu items that you want to be disabled because HyperCard doesn't pay any attention to you if you make one of its items look disabled. A sample DoMenu handler is shown here and another is in the script of this stack. example: on domenu anItem global HelpMenu, Disabled --anItem is the name of the menu item chosen -- HelpMenu is a list of items in my own help menu -- Disabled is the list of items that I have disabled if Disabled contains anItem then answer "HyperCard menu item "&anItem&" is disabled"¬ with "OK" exit domenu else if HelpMenu contains anItem then DoMyHelp anItem -- see which item it is and do something else -- is an enable HyperCard item pass domenu - pass it on down the line exit domenu end if end domenu REVISION HISTORY 1.2d3 first public release version 1.2d4 fix problem with empty item list in AddAMenu 1.2d6 allow arbitrarily long menus in AddAMenu and InsertMenuItem 1.2d7 Fixed positioning problem in "show" command that never worked correctly. Compiled under THINK C™ v.4.0 1.2d10 2/21/90 fixed bug in "insert" operation that put new items 2 slots below desired location in the item list. -- part contents for card part 7 ----- text ----- /* MenuHandler1.2d10.c */ /* © Digital Medicine Inc. 1988 */ /* written in THINK C™ 4.0 © Think Technologies, Inc */ /* by Roger Brown 7/21/88 Courseware Development group */ /* version 1.2d10 fixes a bug in the "insert" option that put items 2 slots below the specified item in the item list. /* version 1.2d8 and 1.2d9 included popup menus but that functionality has moved to the PopList XFCN. /* 9/1/89 version 1.2d7: compiled under THINK C™ 4.0, working on "show" position bug */ /* had to redefine the "show mnu" interface to have a beforeMenu parameter with a default of "at the end". Numbr input is not allowed. It never worked anyway. We clear out all references to me position of the menu when showing and hidding because it has no significance anyway. */ /* 5/5/89 version 1.2d6: Now handles arbitrarily long menu item lists in AddAMenu and InsertMenuItem. */ /* version 1.2d4 will bomb if you insert enough items to make the item list global greater than 255 chars. The Menu Manager dosen't care, just my UpdateItemGlobal procedure. */ /* 5/5/89 version 1.2d4: fix empty list problem in AddAMenu */ /* This is a HyperCard XFCN that handles menus in all sorts of ways. ********************************* *** Requires HC v1.2 or later *** ********************************* HyperCards Syntax is: MenuHandler message,title,other things according to message ex. MenuHandler "Add","Help","Introduction,(----,Glossary" returns: error messages where message is one of these opcodes: Add - adds a new menu parameters are title,item string,before title is the menu title items is string containing the menu items and their states in the normal Mac ToolBox format except for commas instead of semi-colons to make hypertalk level processing easier before is a string that names a menu to insert this one before (if empty, this menu goes at the end of the menu bar) Delete - deletes a menu and its handle parameter is title Hide - hides a menu but remembers it for later restoration parameter is title Show - restores a hidden menu parameter is title,beforeMenu where after menu can be specified or the default is after all menus Insert - inserts a menu item parameters are menu title, item name with format specifications, after item (number or name) Remove - removes a menu item parameters are menu title, item name or number Enable - enables a menu item parameters are menu title, item name or number A number of 0 enables the whole menu Disable - disables a menu item parameters are menu title, item name or number A number of 0 disables the whole menu Mark - checks an item parameters are menu title, item name or number and mark: none,command,check,diamond, or apple A HyperCard global is maintained for every menu added through MenuHandler. The menu items in a menu are found in a HyerCard item list in the global with the menu's name. This makes it easy to test if a doMenu call is for an added menu. ex. global HelpMenu = "Introduction,Getting Started,Glossary" An extra global is maintained that includes a list of all items that are currently disabled. These can be in new menus or in HyperCard's menus. This list is needed because some HyperCard menu actions can still proceed even when their menu items appear to be disabled. To compile: create a project with this, ANSI-A4 and MacTraps. Build as code resource type XFCN named MenuHandler. */ #include "MenuMgr.h" #include "HyperXCmd.h" #include "XCmdGlue.inc.c" #include "SetUpA4.h" #define FALSE 0 #define TRUE !FALSE #define NULL 0L typedef struct MenuRec { MenuHandle menuOH; int menuLeft; } MenuRec; typedef struct DynamicMenuList { /* this is actually a dynamic structure */ int lastMenu; int lastRight; int mbResID; MenuRec menu[64]; /* 64 is an aribtrary number, but plenty big */ } DynamicMenuList,*DMLPtr,**DMLHandle; char isNumber(); long ItemNumber(); MenuHandle GetHiddenMenu(); /* build a return result structure from a string */ ResultIs(paramPtr,theResult) XCmdBlockPtr paramPtr; char *theResult; { long len; Handle resultHandle; len = 1+strlen(theResult); resultHandle = NewHandle(len); BlockMove(theResult,*resultHandle,len); paramPtr->returnValue = resultHandle; } /* change a string into its upper case equivalent */ ucase(s) char *s; { int i; char c; for (i=0;ilen) { /* out of range */ strcpy(dest,""); return; } } c = 0; for (j=i;j len) { /* open up the list global */ len = len + kBlockSize; HUnlock(theList); SetHandleSize(theList,len); if (MemError()!=noErr) { ResultIs(paramPtr,"Out of memory in MenuHandler XCMD"); DisposHandle(theList); return; } HLock(theList); } strcat(*theList,temp); if (iparamCount < 3) { ResultIs(paramPtr,"Not enough parameters in Add."); return; } /* lock down the parameters so we can point to them */ for (i=1;iparamCount;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } /* get the parameters */ theTitle = *(paramPtr->params[1]); theItems = *(paramPtr->params[2]); strcpy(titleStr,theTitle); /* see if we really need to do this */ if (GetMenuID(theTitle)!=0) { ResultIs(paramPtr,"Menu already shown."); for (i=1;iparamCount;i++) HUnlock (paramPtr->params[i]); return; } /* get ready to talk to the menu manager */ CtoPstr((char *)titleStr); /* get an id for this menu */ itsID = 0; while (itsID<128) itsID = UniqueID('MENU'); /* create the menu and insert the items */ theMenu = NewMenu(itsID,titleStr); strcpy(itemStr," "); /* create menu with 1 blank item cuz AppendMenu */ CtoPstr((char*)itemStr); AppendMenu(theMenu,itemStr); /* can't handle a null string */ DelMenuItem(theMenu,1); /* now get rid of the blank menu item */ /* add all items by inserting - so we aren't constrained to 255 char limit */ itemCount = NumHCItems(theItems); for (i=0;iparamCount > 3) { strcpy(beforeStr,*(paramPtr->params[3])); beforeID = GetMenuID(beforeStr); } InsertMenu(theMenu,beforeID); /* update the menu bar */ DrawMenuBar(); /* create the menu global */ PtoCstr((char *)titleStr); UpdateItemGlobal(paramPtr,titleStr); /* clean up */ for (i=1;iparamCount;i++) HUnlock (paramPtr->params[i]); return; } /* delete a menu from the menu bar and remove it from memory */ pascal void DeleteAMenu(paramPtr) XCmdBlockPtr paramPtr; { int i,itsID; Str255 titleStr,itemStr; Ptr theTitle,theItems; MenuHandle theMenu; int theMenuID; Handle empty; /* check parameter count */ if (paramPtr->paramCount < 2) { ResultIs(paramPtr,"Not enough parameters in Delete."); return; } /* lock parameters down so we can point to them */ MoveHHi(paramPtr->params[1]); HLock (paramPtr->params[1]); theTitle = *(paramPtr->params[1]); strcpy(titleStr,theTitle); /* get the id of this menu */ theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) { ResultIs(paramPtr,"MenuHandler error:Can't find menu to delete"); } else { /* get the menu and do the delete */ theMenu = GetMHandle(theMenuID); /* delete it from out save list if it is there */ RemoveFromSaveList(paramPtr,theMenu); /* remove its items from the disabled list */ for (i=0;iparams[1]); return; } /* store a menu title and id in a hidden HyperCard global */ StoreHiddenMenu(paramPtr,title,theMenu) XCmdBlockPtr paramPtr; char *title; MenuHandle theMenu; { Handle theGlobal; Str255 numStr,temp; long len,tempLong; if (GetHiddenMenu(paramPtr,title,&tempLong)!=NULL) { return; /* already stored */ } theGlobal = GetGlobal(paramPtr,"\pXXMHLISTXX"); HLock(theGlobal); NumToString(theMenu,numStr); /* the menu handle */ PtoCstr((char *)numStr); strcpy(temp,title); /* the menu title */ strcat(temp,","); strcat(temp,numStr); strcat(temp,"\15"); /* make it a HyperCard line */ /* add it to the end of the existing global */ len = GetHandleSize(theGlobal) + (long)strlen(temp) + 1; HUnlock(theGlobal); SetHandleSize(theGlobal,len); if (MemError()!=noErr) { ResultIs(paramPtr,"Out of Memory"); DisposHandle(theGlobal); return; } HLock(theGlobal); strcat(*theGlobal,temp); HUnlock(theGlobal); SetGlobal(paramPtr,"\pXXMHLISTXX",theGlobal); DisposHandle(theGlobal); } /* get a hidden menu's id from the hidden HC global. Return its handle. */ MenuHandle GetHiddenMenu(paramPtr,title) XCmdBlockPtr paramPtr; char *title; { Handle theGlobal; MenuHandle theMenu; int i,numLines; Str255 temp,name,idStr; /* get the hidden menu list */ theGlobal = GetGlobal(paramPtr,"\pXXMHLISTXX"); HLock(theGlobal); numLines = NumHCLines(*theGlobal); /* find it in the list */ for (i=0;iparamCount < 2) { ResultIs(paramPtr,"Not enough parameters in Hide."); return; } /* lock the parameters down so we can point to them */ MoveHHi(paramPtr->params[1]); HLock (paramPtr->params[1]); theTitle = *(paramPtr->params[1]); strcpy(titleStr,theTitle); theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) ResultIs(paramPtr,"MenuHandler error:Can't find menu to hide"); else { /* delete the menu from the menu list but remember its name and handle */ theMenu = GetMHandle(theMenuID); DeleteMenu(theMenuID); StoreHiddenMenu(paramPtr,titleStr,theMenu); DrawMenuBar(); } HUnlock (paramPtr->params[1]); return; } /* show a hidden menu */ pascal void ShowMenu(paramPtr) XCmdBlockPtr paramPtr; { int i,tempInt; Str255 titleStr,itemStr,beforeStr; Ptr theTitle; MenuHandle theMenu; int beforeMenuID; /* check parameter count */ if (paramPtr->paramCount < 2) { ResultIs(paramPtr,"Not enough parameters in Show."); return; } /* lock parameters down so we can point to them */ for (i=1;iparamCount;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } theTitle = *(paramPtr->params[1]); strcpy(titleStr,theTitle); ucase(titleStr); beforeStr[0] = 0; if (paramPtr->paramCount>2) strcpy(beforeStr,*paramPtr->params[2]); /* find the menu in the hidden list */ theMenu = GetHiddenMenu(paramPtr,titleStr); if (theMenu==NULL) ResultIs(paramPtr,"MenuHandler error:Can't find menu to show"); else { /* get the before menu */ beforeMenuID = 0; if (strcmp(beforeStr,"")!=0) { beforeMenuID = GetMenuID(beforeStr); } /* move it from hidden to shown */ InsertMenu(theMenu,beforeMenuID); RemoveFromSaveList(paramPtr,theMenu); DrawMenuBar(); } for (i=1;iparamCount;i++) HUnlock (paramPtr->params[i]); return; } /* insert an item into a menu */ pascal void InsertMenuItem(paramPtr) XCmdBlockPtr paramPtr; { int i,itsID,itemCount; Str255 titleStr,itemStr,afterStr; MenuHandle theMenu; int theMenuID; long afterItem; Ptr theItems; /* check paramter count */ if (paramPtr->paramCount < 4) { ResultIs(paramPtr,"Not enough parameters in Insert."); return; } /* lock parameters down so we can point to them */ for (i=1;i<4;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } /* get the parameters */ strcpy(titleStr,*(paramPtr->params[1])); theItems = *(paramPtr->params[2]); strcpy(afterStr,*(paramPtr->params[3])); /* get the menu */ theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) { ResultIs(paramPtr,"MenuHandler error:Can't find menu for insert"); } else { /* get its handle */ theMenu = GetMHandle(theMenuID); CtoPstr((char *)itemStr); /* Is it identified by name or number? */ if (!isNumber(afterStr,&afterItem)) afterItem = ItemNumber(theMenu,afterStr); /* add all items by inserting - so we aren't constrained to 255 char limit */ itemCount = NumHCItems(theItems); for (i=0;iparams[i]); } /* remove an item from a menu */ pascal void RemoveMenuItem(paramPtr) XCmdBlockPtr paramPtr; { int i,itsID; Str255 titleStr,itemStr; Ptr theTitle,theItems; MenuHandle theMenu; int theMenuID; long theItem; /* checkl parameter count */ if (paramPtr->paramCount < 3) { ResultIs(paramPtr,"Not enough parameters in Remove."); return; } /* lock the parameters so we can point to them */ for (i=1;i<3;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } /* get parameters */ strcpy(titleStr,*(paramPtr->params[1])); strcpy(itemStr,*(paramPtr->params[2])); /* get the menu */ theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) ResultIs(paramPtr,"MenuHandler error:Can't find menu for removal request"); else { /* get its handle */ theMenu = GetMHandle(theMenuID); /* is it identified by name or number? */ if (!isNumber(itemStr,&theItem)) theItem = ItemNumber(theMenu,itemStr); /* delete it and update the menu global */ DelMenuItem(theMenu,(int)theItem); UpdateItemGlobal(paramPtr,titleStr); } for (i=1;i<3;i++) HUnlock (paramPtr->params[i]); } /* enable an item in a menu */ pascal void EnableMenuItem(paramPtr) XCmdBlockPtr paramPtr; { int i,itsID; Str255 titleStr,itemStr; Ptr theTitle,theItems; MenuHandle theMenu; int theMenuID; long theItem; /* check parameter count */ if (paramPtr->paramCount < 3) { ResultIs(paramPtr,"Not enough parameters in Enable."); return; } /* lock down parameters so we can point to them */ for (i=1;i<3;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } /* get parameters */ strcpy(titleStr,*(paramPtr->params[1])); strcpy(itemStr,*(paramPtr->params[2])); /* get the menu */ theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) ResultIs(paramPtr,"MenuHandler error:Can't find menu for enable request"); else { /* get its handle */ theMenu = GetMHandle(theMenuID); /* is it identified by name or number? */ if (!isNumber(itemStr,&theItem)) { theItem = ItemNumber(theMenu,itemStr); if (theItem==0L) { /* none to disable */ ResultIs(paramPtr,"Invalid item number in enable"); for (i=1;i<3;i++) HUnlock (paramPtr->params[i]); return; } } EnableItem(theMenu,(int)theItem); if ((int)theItem != 0) { /* update disable global */ RemoveFromDisableGlobal(paramPtr,theMenu,(int)theItem); } else { /* remove all items in it from the disable global */ for (i=0;iparams[i]); } /* disable a menu item */ pascal void DisableMenuItem(paramPtr) XCmdBlockPtr paramPtr; { int i,itsID; Str255 titleStr,itemStr; Ptr theTitle,theItems; MenuHandle theMenu; int theMenuID; long theItem; /* check parameter count */ if (paramPtr->paramCount < 3) { ResultIs(paramPtr,"Not enough parameters in Disable."); return; } /* lock down parameters so we can point to them */ for (i=1;i<3;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } /* get parameters */ strcpy(titleStr,*(paramPtr->params[1])); strcpy(itemStr,*(paramPtr->params[2])); /* get the menu */ theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) ResultIs(paramPtr,"MenuHandler error:Can't find menu for disable request"); else { /* get its handle */ theMenu = GetMHandle(theMenuID); /* is it identified by name or number? */ if (!isNumber(itemStr,&theItem)) { theItem = ItemNumber(theMenu,itemStr); if (theItem==0L) { /* none to disable */ ResultIs(paramPtr,"Invalid item number in disable"); for (i=1;i<3;i++) HUnlock (paramPtr->params[i]); return; } } /* disable it */ DisableItem(theMenu,(int)theItem); /* update the disabled menu global */ if ((int)theItem != 0) { AddToDisableGlobal(paramPtr,theMenu,(int)theItem); } else { for (i=0;iparams[i]); } /* mark a menu item */ pascal void MarkMenuItem(paramPtr) XCmdBlockPtr paramPtr; { int i,itsID; Str255 titleStr,itemStr,markStr; Ptr theTitle,theItems; MenuHandle theMenu; int theMenuID; long theItem; char markChar; /* checl parameter count */ if (paramPtr->paramCount < 4) { ResultIs(paramPtr,"Not enough parameters in Mark."); return; } /* lock down the parameters so we can point to them */ for (i=1;i<4;i++) { MoveHHi(paramPtr->params[i]); HLock (paramPtr->params[i]); } /* get parameters */ strcpy(titleStr,*(paramPtr->params[1])); strcpy(itemStr,*(paramPtr->params[2])); /* get the menu */ theMenuID = GetMenuID(titleStr); if (theMenuID==NULL) ResultIs(paramPtr,"MenuHandler error:Can't find menu for mark request"); else { /* get its handle */ theMenu = GetMHandle(theMenuID); /* is it identified by name or number? */ if (!isNumber(itemStr,&theItem)) { theItem = ItemNumber(theMenu,itemStr); if (theItem==0L) { /* none to mark */ ResultIs(paramPtr,"Invalid item number in mark"); for (i=1;i<4;i++) HUnlock (paramPtr->params[i]); return; } } /* decode the mark parameter */ strcpy(markStr,*(paramPtr->params[3])); ucase(markStr); if (strcmp(markStr,"NONE")==0) markChar = noMark; else if (strcmp(markStr,"COMMAND")==0) markChar = commandMark; else if (strcmp(markStr,"CHECK")==0) markChar = checkMark; else if (strcmp(markStr,"DIAMOND")==0) markChar = diamondMark; else if (strcmp(markStr,"APPLE")==0) markChar = appleMark; else { ResultIs(paramPtr,"Unknown mark type."); return; } /* set the mark */ SetItemMark(theMenu,theItem,markChar); } for (i=1;i<4;i++) HUnlock (paramPtr->params[i]); } /* XCMD entry point */ pascal void main(paramPtr) XCmdBlockPtr paramPtr; /* this is the entry point for the XFCN */ { Handle taskHandle,portHandle; Str255 temp; RememberA0(); SetUpA4(); /* use global variables */ /* get the opcode */ if (paramPtr->paramCount==0) { ResultIs(paramPtr,"No parameters in MenuHandler."); RestoreA4(); return; } taskHandle = paramPtr->params[0]; ucase(*taskHandle); /* branch on the opcode */ if (strcmp(*taskHandle,"ADD")==0) AddAMenu(paramPtr); else if (strcmp(*taskHandle,"DELETE")==0) DeleteAMenu(paramPtr); else if (strcmp(*taskHandle,"HIDE")==0) HideMenu(paramPtr); else if (strcmp(*taskHandle,"SHOW")==0) ShowMenu(paramPtr); else if (strcmp(*taskHandle,"INSERT")==0) InsertMenuItem(paramPtr); else if (strcmp(*taskHandle,"REMOVE")==0) RemoveMenuItem(paramPtr); else if (strcmp(*taskHandle,"ENABLE")==0) EnableMenuItem(paramPtr); else if (strcmp(*taskHandle,"DISABLE")==0) DisableMenuItem(paramPtr); else if (strcmp(*taskHandle,"MARK")==0) MarkMenuItem(paramPtr); else { strcpy(temp,"MenuHandler Error: unknown message "); strcat(temp,*taskHandle); ResultIs(paramPtr,temp); } RestoreA4(); return; }